import { Object3D,Matrix4 } from 'three';
import { Command } from '../command.js';
import { Editor } from '../editor.js';

/**
 * @param editor Editor
 * @param object THREE.Object3D
 * @param newParent THREE.Object3D
 * @param newBefore THREE.Object3D
 * @constructor
 */
class MoveObjectCommand extends Command {
	object:Object3D;
	oldParent:Object3D|undefined|null;
	oldIndex?:number;
	newParent:Object3D|undefined;
	newIndex:number|undefined;
	newBefore:Object3D|undefined;
	constructor( editor:Editor, object:Object3D, newParent?:Object3D, newBefore?:Object3D ) {

		super( editor );
		// this.editor.outline.moveObject(object,newParent,newBefore);
		this.type = 'MoveObjectCommand';
		this.name = 'Move Object';

		this.object = object;
		this.oldParent = ( object !== undefined ) ? object.parent : undefined;
		this.oldIndex = ( this.oldParent !== undefined ) ? this.oldParent?.children.indexOf( this.object ) : undefined;
		this.newParent = newParent;

		if ( newBefore !== undefined ) {

			this.newIndex = ( newParent !== undefined ) ? newParent.children.indexOf( newBefore ) : undefined;

		} else {

			this.newIndex = ( newParent !== undefined ) ? newParent.children.length : undefined;

		}

		if ( this.oldParent === this.newParent && this.newIndex!==undefined&&this.oldIndex!=undefined&& this.newIndex > this.oldIndex ) {

			this.newIndex --;

		}

		this.newBefore = newBefore;


	}

	execute() {

		// 获取世界位置和旋转
		this.object.updateMatrixWorld();

		// 获取当前世界变换
		const worldMatrix = this.object.matrixWorld.clone();

		this.oldParent?.remove( this.object );

		const children = this.newParent?.children;
		if(children&&this.newIndex!=undefined){
			children.splice( this.newIndex, 0, this.object );
		}

		if(this.newParent){
			this.newParent.updateMatrixWorld();
		
			this.object.parent = this.newParent||null;

			
			// 计算相对于新父级的本地变换
			const inverseParentMatrix = new Matrix4()
				.copy(this.newParent.matrixWorld)
				.invert();
			
			const newLocalMatrix = new Matrix4()
				.multiplyMatrices(inverseParentMatrix, worldMatrix);
			
			// 应用新的本地变换
			newLocalMatrix.decompose(this.object.position, this.object.quaternion, this.object.scale);
			
		}
		// 更新矩阵
		this.object.updateMatrix();

		this.object.dispatchEvent( { type: 'added' } );
		this.editor.signals.sceneGraphChanged.dispatch();

	}

	undo() {
		// this.editor.outline.removeObject(this.object);
		this.newParent?.remove( this.object );

		// this.editor.outline.addObject(this.object,this.oldParent,this.oldIndex);
		const children = this.oldParent?.children;
		if(children&&this.oldIndex!=undefined){
			children.splice( this.oldIndex, 0, this.object );
		}
		
		
		this.object.parent = this.oldParent||null;
		

		this.object.dispatchEvent( { type: 'added' } );
		this.editor.signals.sceneGraphChanged.dispatch();

	}


}

export { MoveObjectCommand };
